# 冒泡排序
def bubble_sort(nums):
    i = 1
    exchanged = True
    while i < len(nums) and exchanged:
        exchanged = False
        for j in range(len(nums) - i):
            if nums[j] > nums[j + 1]:
                nums[j], nums[j + 1] = nums[j + 1], nums[j]
                exchanged = True
        i += 1
    return nums
 
 
# 快速排序
def quick_sort(nums, left=0, right=None):
    if right == None:
        right = len(nums) - 1
    if left >= right:
        return nums
    low = left
    high = right
    key = nums[left]
    while left < right:
        while left < right and nums[right] >= key:
            right -= 1
        nums[left], nums[right] = nums[right], nums[left]
        while left < right and nums[left] <= key:
            left += 1
        nums[left], nums[right] = nums[right], nums[left]
    quick_sort(nums, low, left - 1)  # 递归
    quick_sort(nums, right + 1, high)  # left == right
    return nums
 
 
# 插入排序
def insert_sort(nuns):
    for i in range(1, len(nums)):
        key = nums[i]
        i -= 1
        while i >= 0 and nums[i] > key:
            nums[i + 1] = nums[i]
            i -= 1
        nums[i + 1] = key
    return nums
 
 
# 希尔排序
def shell_sort(nums):
    gap = len(nums) // 2  # 初始增量，//整除
    while gap > 0:
        # 缩小增量，直至增量为1
        for i in range(0, gap):
            # 分组
            j = i + gap
            while j < len(nums):
                # 组内插入排序
                key = nums[j]
                k = j - gap
                while k >= 0 and nums[k] > key:
                    nums[k + gap] = nums[k]
                    k -= gap
                nums[k + gap] = key
                j += gap
        gap //= 2
    return nums
 
 
# 选择排序
def select_sort(nums):
    for i in range(len(nums)):
        minimum = i
        for j in range(i + 1, len(nums)):
            if nums[j] < nums[minimum]:
                minimum = j
        nums[i], nums[minimum] = nums[minimum], nums[i]
    return nums
 
 
# 堆排序
def max_heapify(nums, i, size):
    # 最大堆调整
    # 注意数组的size比数组的最大索引大1
    lchild = 2 * i + 1
    rchild = 2 * i + 2
    maximum = i
    if i < size // 2:
        if nums[lchild] > nums[maximum]:
            maximum = lchild
        if rchild < size:
            # 肯定有左子节点，未必有右子节点
            if nums[rchild] > nums[maximum]:
                maximum = rchild
        if maximum != i:
            nums[i], nums[maximum] = nums[maximum], nums[i]
            max_heapify(nums, maximum, size)  # 递归
def build_max_heap(nums, size):
    # 创建最大堆
    for i in range(size // 2 - 1, -1, -1):
        max_heapify(nums, i, size)
def heap_sort(nums):
    size = len(nums)
    build_max_heap(nums, size)
    for i in range(1, size):
        nums[0], nums[size - i] = nums[size - i], nums[0]
        max_heapify(nums, 0, size - i)
    return nums
 
 
# 归并排序
def merge_sort(nums):
    length = len(nums)
    if length <= 1:
        return nums
    list1 = merge_sort(nums[: length // 2])
    list2 = merge_sort(nums[length // 2:])  # 递归
    i = 0
    j = 0
    k = 0
    while i < len(list1) and j < len(list2):
        if list1[i] < list2[j]:
            nums[k] = list1[i]
            i += 1
            k += 1
        else:
            nums[k] = list2[j]
            j += 1
            k += 1
        nums = nums[: k] + list1[i:]
        nums = nums[: k] + list2[j:]  # 其中一个为空列表
    return nums
 
 
# 基数排序
def radix_sort(nums):
    maximum = nums[0]
    for num in nums:
        # 找到最大值
        if num > maximum:
            maximum = num
    k = 1
    while maximum // (10 ** k) > 0:
        # 判定最大值是几位数
        k += 1
    for i in range(k):
        buckets = [[] for x in range(10)]
        for num in nums: 
            buckets[(num // (10 ** i)) % 10].append(num)
        nums = []
        for b in buckets:
            nums += b
    return nums
 
 
# 测试
nums0 = list(range(200))
nums = list(range(200))
random.shuffle(nums)
print(bubble_sort(nums) == nums0)
print(quick_sort(nums) == nums0)
print(insert_sort(nums) == nums0)
print(shell_sort(nums) == nums0)
print(select_sort(nums) == nums0)
print(heap_sort(nums) == nums0)
print(merge_sort(nums) == nums0)
print(radix_sort(nums) == nums0)